package com.nauu.atombuilder.generator;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;

import com.nauu.atombuilder.Activator;
import com.nauu.atombuilder.modle.Connection;
import com.nauu.atombuilder.modle.Dialog;
import com.nauu.atombuilder.modle.Node;
import com.nauu.atombuilder.pojo.Act;
import com.nauu.atombuilder.pojo.Column;
import com.nauu.atombuilder.pojo.Form;
import com.nauu.atombuilder.pojo.Grid;

import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
@SuppressWarnings("unchecked")
public class ModelGenerator {

	public static final String GRID_TLP = "grid.ftl";

	public static final String FORM_TLP = "form.ftl";

	public static final String SHORTCU_TLP = "shortcut.ftl";

	public static final String DISPATCH_TLP = "dispatch.ftl";
	
	public static final String Grid_DATA_TLP = "testGridData.ftl";

	public static final String FORM_DATA_TLP = "testFormData.ftl";
	
	public void execute(String workspacePath,String projectPath,String projectName,List<Node> nodes,Shell shell){
		try {
			Configuration cfg = new Configuration();
			 //从什么地方加载freemarker模板文件  
			cfg.setTemplateLoader(new ClassTemplateLoader(Activator.class, "tlps"));  
			
			 //设置对象包装器  
			cfg.setObjectWrapper(new DefaultObjectWrapper());  
			 //设置异常处理器  
			cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
			
			List<Node> dispatch = new ArrayList<Node>();
			for (Node node : nodes) {
				if(node instanceof com.nauu.atombuilder.modle.Grid){
					makeGrid(workspacePath,projectName,cfg,(com.nauu.atombuilder.modle.Grid)node,shell);
				}else if(node instanceof com.nauu.atombuilder.modle.Form){
					makeForm(workspacePath,projectName,cfg,(com.nauu.atombuilder.modle.Form)node,shell);
				}
				
				if(node.isVisible()){
					dispatch.add(node);
				}
			}
			
			makeDispatch(cfg,projectPath,projectName,dispatch);
		} catch (Exception e) {
			MessageDialog.openInformation(
					shell,
					"111",
					e.toString());
			e.printStackTrace();
		}
	}
	
	private void makeGrid(String projectPath,String projectName,Configuration cfg,com.nauu.atombuilder.modle.Grid modle,Shell shell){
		
		List<Column> colList = new ArrayList<Column>();
		Method method1,method2;
		Object colName,colMapping;
		for(int index=1;index<=9;index++){
			try {
				method1 = modle.getClass().getMethod("getColName"+index, new Class[]{});
				colName = method1.invoke(modle);
				method2 = modle.getClass().getMethod("getColMapping"+index, new Class[]{});
				colMapping = method2.invoke(modle);
				
				if(colName != null && !colName.equals("")){
					Column column = new Column();
					column.setName(""+colName);
					column.setMapping(""+colMapping);
					colList.add(column);
				}
				
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		
		Grid grid = new Grid();
		grid.setId(modle.getId());
		grid.setName(modle.getName());
		grid.setMode(modle.getMode()==true?"loop":"pop");
		grid.setCheckbox(""+modle.getCheckbox());
		grid.setUsePage(""+modle.getUsePage());
		grid.setColumns(colList);
		
		List<Connection> conns = modle.getOutgoingConnections();
		for (Connection connection : conns) {
			Node node = connection.getTarget();
			Map map = new HashMap();
			
			if(node instanceof Dialog){
				if(((Dialog)node).getType()==0){
					
				}
				map.put("type", ((Dialog)node).getType());
				map.put("text", ((Dialog)node).getName());
			}else{
				map.put("type", 2);
			}
			
			map.put("name", connection.getActName());
			map.put("path", connection.getTarget().getPath());
			switch (connection.getActType()) {
			case 0:
				grid.getTrackActs().add(map);
				break;
			case 1:
				grid.getClipActs().add(map);
				break;
			case 2:
				grid.getGridActs().add(map);
				break;

			default:
				break;
			}
		}
		String serviceName = projectName;
		if(serviceName.startsWith("g")){
			serviceName = serviceName.substring(1, serviceName.length());
		}
		Map root = new HashMap();  
		root.put("grid", grid);
		root.put("serviceName", serviceName);
		String path = (projectPath+modle.getPath()).replaceAll("//", "/");
		doExec(cfg, path,GRID_TLP, root,shell);
	}
	
	private void makeForm(String projectPath,String projectName,Configuration cfg,com.nauu.atombuilder.modle.Form modle,Shell shell){
		
		Form form = new Form();
		form.setId(modle.getId());
		form.setName(modle.getName());
		form.setMode(modle.getMode()==true?"loop":"pop");
		
		List<Connection> conns = modle.getOutgoingConnections();
		for (Connection connection : conns) {
			Map map = new HashMap();
			map.put("name", connection.getActName());
			map.put("path", connection.getTarget().getPath());
			switch (connection.getActType()) {
			case 0:
				form.getTrackActs().add(map);
				break;
			case 1:
				form.getClipActs().add(map);
				break;
			default:
				break;
			}
		}
		String serviceName = projectName;
		if(serviceName.startsWith("g")){
			serviceName = serviceName.substring(1, serviceName.length());
		}
		Map root = new HashMap();  
		root.put("form", form);
		root.put("serviceName", serviceName);
		String path = (projectPath+modle.getPath()).replaceAll("//", "/");
		doExec(cfg, path,FORM_TLP, root,shell);
	}
	
	private void makeDispatch(Configuration cfg,String projectPath,String projectName,List<Node> list){
		String path = projectPath+"/testdata";
		String serviceName = projectName;
		if(serviceName.startsWith("g")){
			serviceName = serviceName.substring(1, serviceName.length());
		}
		Map root = new HashMap();
		root.put("id", Calendar.getInstance().getTimeInMillis());
		root.put("name", "测试应用");
		root.put("dispatch", projectName+"/dispatch.js");
		root.put("list", list);
		try {
			File file = new File(path);
			if(!file.exists()){
				file.mkdirs();
			}
			Template template = cfg.getTemplate(SHORTCU_TLP);
			template.setEncoding("UTF-8");
			//定义输出  
			
			PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(path+"/shortcut.js")),"UTF-8"));  
			template.process(root, out);
			out.close();
			
			template = cfg.getTemplate(Grid_DATA_TLP);  
			//定义输出  
			out = new PrintWriter(new BufferedWriter(new FileWriter(path+"/"+serviceName+".testAction.testGrid.gjs")));  
			template.process(root, out);
			out.close();
			
			template = cfg.getTemplate(FORM_DATA_TLP);  
			//定义输出  
			out = new PrintWriter(new BufferedWriter(new FileWriter(path+"/"+serviceName+".testAction.testForm.gjs")));  
			template.process(root, out);
			out.close();
			
			template = cfg.getTemplate(DISPATCH_TLP);  
			//定义输出  
			out = new PrintWriter(new BufferedWriter(new FileWriter(projectPath+"/dispatch.js")));  
			template.process(root, out);
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	private void doExec(Configuration cfg,String dir,String tlpType,Map root,Shell shell){
		try {
			 Template template = cfg.getTemplate(tlpType);
			 template.setEncoding("UTF-8");
			 //定义输出  
			 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(dir)));  
			 template.process(root, out);
			 out.close();
		} catch (Exception e) {
			MessageDialog.openInformation(
					shell,
					"Popupmenu",
					e.toString());
			e.printStackTrace();
		} 
	}
	
	
	public static void main(String[] args) {
		try {
//			InputStream is = AtomBuilderPlugin.class.getResourceAsStream("/tlp/grid.ftl");
//			System.out.println(is);
//			System.out.println(AtomBuilderPlugin.class.getResource("").getPath());
			String dir = System.getProperty("user.dir")+"\\tlp";
			 Configuration cfg = new Configuration();  
			 
			 //从什么地方加载freemarker模板文件  
			 cfg.setDirectoryForTemplateLoading(new File(dir));  
			   
			 //设置对象包装器  
			 cfg.setObjectWrapper(new DefaultObjectWrapper());  
			   
			 //设置异常处理器  
			 cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
			 
			//定义Template对象  
            Template template = cfg.getTemplate("grid.ftl");  
            Grid grid = new Grid();
            grid.setId("test123");
            
            Column column1 = new Column();
            column1.setName("字段1");
            column1.setMapping("field1");
            column1.setWidth("100");
            
            Column column2 = new Column();
            column2.setName("字段2");
            column2.setMapping("field2");
            column2.setWidth("200");
            List columns = new ArrayList();
            columns.add(column1);
            columns.add(column2);
            
            Act act1 = new Act();
            act1.setName("按钮1");
            Act act2 = new Act();
            act2.setName("按钮2");
            List gridActs = new ArrayList();
            gridActs.add(act1);
            gridActs.add(act2);
            
            
            grid.setColumns(columns);
            grid.setGridActs(gridActs);
			 Map root = new HashMap();  
	         root.put("grid", grid);  
	           
	         //定义输出  
	         PrintWriter out   
	             = new PrintWriter(  
	                 new BufferedWriter(  
	                     new FileWriter(dir+"\\out.js")  
	                 )  
	             );  
	           
	         //****最重要的就是这一步，动态加载“世界，你好”到abc所在的位置  
	         template.process(root, out);  
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
	}
}
